﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
#if SILVERLIGHT
using AbstraX.ClientInterfaces;
#else
using AbstraX.ServerInterfaces;
#endif
using System.Reflection;
using AbstraX.XPathBuilder;
using System.Linq;
using System.Xml.Schema;
using System.Diagnostics;
using System.ServiceModel.DomainServices.Server;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using MvvmTreeView;
using AbstraX;
using AbstraX.Templates;
using AbstraX.AssemblyInterfaces;
using AbstraX.Contracts;

namespace AssemblyProvider.Web.Entities
{
    [DataContract, NodeImage("AssemblyProvider.Web.Images.Field.png"), DebuggerDisplay("{ DebugInfo }"), ClientCodeGeneration(typeof(AbstraXClientInterfaceGenerator))]
    public class FieldAttribute : IAttribute, IFieldAttribute
    {
        private FieldInfo field;
        private IBase parent;
        private string queryWhereProperty;
        private object queryWhereValue;
        private float childOrdinal;
        private string imageURL;

        public FieldAttribute()
        {
        }
        IAbstraXExtension IBase.LoadExtention(IBase baseObject, ITreeNode treeNode)
        {
            return null;
        }
        public FieldAttribute(FieldInfo field, IBase parent)
        {
            this.field = field;
            this.parent = parent;
            this.childOrdinal = 2;

            if (parent.Kind == DefinitionKind.Enumeration)
            {
                imageURL = "AssemblyProvider.Web.Images.EnumItem.png";
            }
            else
            {
                imageURL = "AssemblyProvider.Web.Images.Field.png";
            }
        }

        [DataMember]
        public float ChildOrdinal
        {
            get
            {
                return childOrdinal;
            }
        }

        [DataMember]
        public string DebugInfo
        {
            get
            {
                return this.Name + ID;
            }
        }

        [Include, Association("Parent_BaseType", "ID", "ParentID"), ClientCodeGeneration(typeof(AbstraXClientInterfaceGenerator))]
        public ScalarType DataType
        {
            get
            {
                var type = typeof(AssemblyType);

                return new ScalarType
                {
                    FullyQualifiedName = type.FullName,
                    Name = type.Name,
                    ID = type.FullName
                };
            }
        }

        [DataMember, Key]
        public string ID
        {
            get 
            {
                return this.MakeID("Field='" + field.Name + "'");
            }
        }

        [DataMember]
        public string ParentID
        {
            get
            {
                return this.Parent.ID;
            }
        }

        [DataMember]
        public string Name
        {
            get 
            {
                return field.Name;
            }
        }

        [DataMember]
        public string Description
        {
            get
            {
                return string.Empty;
            }
        }

        [DataMember]
        public string Documentation
        {
            get
            {
                return string.Empty;
            }
        }

        [DataMember]
        public string ImageURL
        {
            get
            {
                return imageURL;
            }
        }

        [DataMember]
        public IBase Parent
        {
            get
            {
                return parent;
            }
        }

        [DataMember]
        public string FolderKeyPair { get; set; }

        public void ExecuteWhere(string property, object value)
        {
            if (value is XPathAxisElement && (property == "ID" || property == "ParentID"))
            {
                var predicate = ((XPathAxisElement)value).Predicates.First();

                queryWhereProperty = predicate.Left;
                queryWhereValue = predicate.Right;
            }
            else
            {
                Debugger.Break();

                queryWhereProperty = property;
                queryWhereValue = value;
            }
        }

        public void ExecuteWhere(System.Linq.Expressions.Expression expression)
        {
        }

        public void ExecuteWhere(XPathAxisElement element)
        {
        }

        public void ClearPredicates()
        {
            queryWhereProperty = null;
            queryWhereValue = null;
        }

        public IRoot Root
        {
            get
            {
                IBase baseObject = this;

                while (baseObject != null)
                {
                    baseObject = baseObject.Parent;

                    if (baseObject is IRoot)
                    {
                        return (IRoot)baseObject;
                    }
                }

                return null;
            }
        }


        [DataMember]
        public DefinitionKind Kind
        {
            get 
            {
                return DefinitionKind.Field;
            }
        }

        [DataMember]
        ScalarType IAttribute.DataType
        {
            get
            {
                var type = field.FieldType;

                return new ScalarType
                {
                    FullyQualifiedName = type.AssemblyQualifiedName,
                    Name = type.Name,
                    ID = type.FullName
                };
            }
        }

        public System.Collections.Generic.IEnumerable<IElement> ChildElements
        {
            get { throw new NotImplementedException(); }
        }

        [DataMember]
        public bool HasChildren
        {
            get 
            {
                return false;
            }
        }

        [DataMember, Include, Association("Parent_Facet", "ID", "ParentID")]
        public Facet[] Facets
        {
            get
            {
                return null;
            }
        }
    }
}
